﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Watson.TemporaryFilesDeleter.UI.Windows
{
    /// <summary>
    /// User control for editing a settings collection.
    /// </summary>
    public partial class SettingsEditor : UserControl
    {
        #region Private Fields

        /// <summary>
        /// The settings being edited.
        /// </summary>
        private Watson.TemporaryFilesDeleter.Properties.Settings settings;

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets or sets the settings being edited.
        /// </summary>
        public Watson.TemporaryFilesDeleter.Properties.Settings Settings
        {
            get
            {
                return this.settings;
            }
            set
            {
                if (this.settings != value)
                {
                    this.settings = value;

                    OnSettingsChanged();
                }
            }
        }

        #endregion

        #region Event Handlers

        private void btnBrowseLogFilePath_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog()
            {
                AddExtension    = true,
                CheckPathExists = true,
                DefaultExt      = "log",
                FileName        = "wtfd.log",
                Filter          = "All files (*.*)|*.*|"
                                + "Log files (*.log)|*.log",
                FilterIndex     = 1
            };

            if (!String.IsNullOrWhiteSpace(this.txtLogFilePath.Text))
            {
                saveFileDialog.FileName = txtLogFilePath.Text;
            }

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                this.txtLogFilePath.Text = saveFileDialog.FileName;
            }
        }

        private void chkWriteLogFile_CheckedChanged(object sender, EventArgs e)
        {
            this.SetControlEnabledState();
        }
        
        private void lblLogFilePath_Click(object sender, EventArgs e)
        {
            this.txtLogFilePath.Focus();
        }

        private void lblLogLevel_Click(object sender, EventArgs e)
        {
            this.cboLogLevel.Focus();
        }

        private void settings_PropertyChanged(object sender, 
            PropertyChangedEventArgs e)
        {
            // Bug out if no event args.
            if (e == null)
                return;


            if (e.PropertyName == "BufferLogFileWriting")
            {
                chkBufferLogFileWriting.Checked = 
                    settings.BufferLogFileWriting;
            }


            if (e.PropertyName == "LogFilePath")
            {
                txtLogFilePath.Text = settings.LogFilePath;
            }
            

            if (e.PropertyName == "LogLevel")
            {
                cboLogLevel.Text = settings.LogLevel.ToString();
            }


            if (e.PropertyName == "WriteLogFile")
            {
                chkWriteLogFile.Checked = settings.WriteLogFile;
            }


            SetControlEnabledState();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Assigns event handlers.
        /// </summary>
        private void AttachEventHandlers()
        { }
        
        /// <summary>
        /// Populates the various combo boxes on the form with suitable values.
        /// </summary>
        private void PopulateComboBoxes()
        {
            /*
             * Provide log level options.
             */
            this.cboLogLevel.DataSource = Enum.GetNames(typeof(LogLevel));
        }

        /// <summary>
        /// Reads settings and sets appropriate values to form controls.
        /// </summary>
        private void ReadSettings()
        {
            // Bug out if no settings available.
            if (this.settings == null)
                return;


            cboLogLevel.Text                = settings.LogLevel.ToString();
            chkWriteLogFile.Checked         = settings.WriteLogFile;
            txtLogFilePath.Text             = settings.LogFilePath;
            chkBufferLogFileWriting.Checked = settings.BufferLogFileWriting;
        }

        /// <summary>
        /// Saves settings from form controls back to settings class and
        /// persists to disk (if appropriate).
        /// </summary>
        private void SaveSettings()
        {
            // Bug out if no settings available.
            if (this.settings == null)
                return;


            settings.LogLevel             = 
                (LogLevel)Enum.Parse(typeof(LogLevel), 
                    cboLogLevel.SelectedItem.ToString());
            settings.WriteLogFile         = chkWriteLogFile.Checked;
            settings.LogFilePath          = txtLogFilePath.Text;
            settings.BufferLogFileWriting = chkBufferLogFileWriting.Checked;

            settings.Save();
        }

        /// <summary>
        /// Sets the enabled state of all controls on the form with regard to
        /// whether there action can currently be performed, etc.
        /// </summary>
        private void SetControlEnabledState()
        {
            /*
             * Set enabled state of controls related to settings controlling
             * how/where the log file is written taking into account whether a
             * log file is to be written at all.
             */
            lblLogFilePath.Enabled          = chkWriteLogFile.Checked;
            txtLogFilePath.Enabled          = chkWriteLogFile.Checked;
            btnBrowseLogFilePath.Enabled    = chkWriteLogFile.Checked;
            chkBufferLogFileWriting.Enabled = chkWriteLogFile.Checked;
        }

        /// <summary>
        /// Sets the initial view state of the various controls on the control.
        /// </summary>
        private void SetInitialViewState()
        { }

        /// <summary>
        /// Occurs when the settings source has changed.
        /// </summary>
        private void OnSettingsChanged()
        {
            ReadSettings();

            SetControlEnabledState();

            /*
             * Listen for property values changing on the settings edited.
             */
            if (this.settings != null)
            {
                this.settings.PropertyChanged += settings_PropertyChanged;
            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Saves the edited settings.
        /// </summary>
        public void Save()
        {
            SaveSettings();
        }

        #endregion

        #region Public Constructors

        /// <summary>
        /// Initialises a new instance of the SettingsEditor class.
        /// </summary>
        public SettingsEditor()
        {
            InitializeComponent();

            PopulateComboBoxes();
            SetInitialViewState();
            SetControlEnabledState();
            AttachEventHandlers();
        }

        #endregion
    }
}
